const fs = require('fs')
const path = require('path')
const send = require('koa-send');
const rmdir = require('../tools/file').rmdir
const mkdirsSync = require('../tools/file').mkdirsSync
const UploadPath = require('../config').UPLOAD_PATH  // 文件上传目录
const DownloadPath = require('../config').DOWNLOAD_PATH
const DownloadRoute = require('../config').DOWNLOAD_ROUTE
const File = require('../models/file')
const standardObj = require('../tools/setOutput').standardObj
 
 
const saveFileModel = function(ctx, newFileName, oldFileName) { 
  const result = {
    data: null,
    code: 0,
    msg: '成功'
  }  
  return new File({
    fileName: newFileName,
    originName: oldFileName,
    url: path.join(DownloadRoute, newFileName), // `${DownloadRoute}\\${newFileName}`,
    _id: `${oldFileName}@${path.join(DownloadRoute, newFileName)}`, // ${DownloadRoute}\\${newFileName} 
    isRelated: false
  }).save().then((res) => {
    result.data = standardObj(res.toObject())
    ctx.response.body = result
    return Promise.resolve(result)
  })   
} 


class FileController { 
  prefix = '' 
  getPath(name){
    return name ? `/${this.prefix}/${name}` : `/${this.prefix}`
  } 

  async upload(ctx, next) {
    
    const file = ctx.request.files.file; // 获取上传文件
     
    const readStream = fs.createReadStream(file.path)  
    const fileName = file.name.split('.')[0]
    const fileExt = file.name.split('.')[1]
    const newFileName = `${fileName}_${new Date().getTime()}.${fileExt}`
    const oldFileName = `${fileName}.${fileExt}` 
    const filePath = UploadPath + `/${newFileName}` 
    const writeStream = fs.createWriteStream(filePath)
   
    
    if (!fs.existsSync(UploadPath)) {
      fs.mkdir(UploadPath, async(err) => {
        if (err) {
          throw new Error(err)
        } else {
          readStream.pipe(writeStream)
          await saveFileModel(ctx, newFileName, oldFileName)
        }
      })
    } else {
      readStream.pipe(writeStream)
      await saveFileModel(ctx, newFileName, oldFileName) 
    }  
  } 
  

  async download(ctx, next) {
    const name = ctx.request.body.name; 
    const url = path.join(DownloadPath, name) 
    ctx.attachment(url)
    await send(ctx, url) 
  } 

  async downloadById(ctx, next) {
    console.log('fileId', ctx.query.id)
    const [err, data] = await to(File.findById(ctx.query.id).lean()) 
    if(err || !data) return ctx.throw(500, err) 
    if (data) {
      ctx.response.body = {
        data: standardObj(data),
        code: 0,
        msg: '成功'
      }
    }
  }

  async uploadBigFile(ctx, next) {
    // console.log(ctx.request.files.file.path)
    const { timestamp, name, size, total, index } = ctx.request.body 
    const chunksPath = path.join(UploadPath, `/file_temp${timestamp}/`)

    if(!fs.existsSync(chunksPath)){ // 判断文件夹是否存在
      mkdirsSync(chunksPath) 
    } 
    const readStream = fs.createReadStream(ctx.request.files.file.path);
    const writeStream = fs.createWriteStream(chunksPath + timestamp + name);
    readStream.pipe(writeStream)
    readStream.on('end', () => {
      fs.unlinkSync(ctx.request.files.file.path);
    });
 
    ctx.body = {
      data: 'done',
      code: 0,
      msg: '成功'
    } 
  }

  async uploadBigFileMerge(ctx, next) {
    const { timestamp, name, size, total, index } = ctx.request.body 
    const chunksPath = path.join(UploadPath, `/file_temp${timestamp}/`)

    const filePath = path.join(UploadPath, timestamp + name)

    const chunks = fs.readdirSync(chunksPath) // 读取目录下的所有文件

    if(chunks.length != total || chunks.length == 0) {
      ctx.body={
        data: null,
        code: 1,
        msg: '切片文件数量不符合'
      };
      chunks.forEach((item)=>{
        fs.unlinkSync(chunksPath + item);
      });
      fs.rmdirSync(chunksPath);
      return;
    }else{
      fs.writeFileSync(filePath, ''); 
      for (let i = 0; i < total; i++) {
          console.log('index', i)
          // 追加写入到文件中
          fs.appendFileSync(filePath, fs.readFileSync(chunksPath + timestamp + name + '.' + i));
          // 删除本次使用的chunk
          fs.unlinkSync(chunksPath + timestamp + name + '.' + i);
      }
      // console.log('开始删除')
      setTimeout(() => {
        fs.rmdir(chunksPath, () => {console.log('文件删除完毕')});
      }, 100)
      
      // 文件合并成功，可以把文件信息进行入库。
      ctx.body = {
        code: 0,
        msg: '切片文件合并成功',
        data: {
          url: timestamp + name
        }
      };
    }
  
  }
}

module.exports = new FileController()